package com.zhiwang.xiaoqu.mvp.model

import android.content.res.Resources
import android.util.Log
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.annotations.SerializedName
import com.hiray.exception.ExpiredException
import com.zhiwang.xiaoqu.BuildConfig
import com.zhiwang.xiaoqu.mvp.model.sharepref.PrefManager
import io.reactivex.ObservableSource
import io.reactivex.Observer
import io.reactivex.functions.Function
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import okio.Buffer
import okio.GzipSource
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.net.Proxy
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import java.util.concurrent.TimeUnit
import javax.inject.Inject

class RestApiHelper @Inject constructor(var gson: Gson, var tslProvider: TslProvider) {


    fun create(): RestApi {
        var httpLoggingInterceptor = HttpLoggingInterceptor(OkHttpLogger())
//        val cookieManager = CookieManager()
//        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL)
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        val builder = OkHttpClient.Builder()
        builder
            .addInterceptor {
                it.proceed(
                    it.request().newBuilder()
                        .addHeader("apptoken", PrefManager.token())
                        .addHeader("appdevice", "android")
                        .addHeader("plat", BuildConfig.ChannelId)
                        .addHeader("appversion", BuildConfig.VERSION_CODE.toString())
                        .addHeader("device-density", Resources.getSystem().displayMetrics.density.toString())
                        .build()
                )
            }
            //不走代理，避免有些用户的设备上挂载了代理，抓取应用信息或者是因为代理网络的原因导致不必要的问题
            // （当然这样并不能完全阻止抓包）
            .proxy(Proxy.NO_PROXY)
        if (BuildConfig.DEBUG)
            builder.addNetworkInterceptor(httpLoggingInterceptor)

        builder.addNetworkInterceptor(RestApiResponseInterceptor)

        val okClient = builder
            .connectTimeout(10000L, TimeUnit.MILLISECONDS)
            .retryOnConnectionFailure(true)
            .sslSocketFactory(tslProvider.sslSocketFactory, tslProvider.trustManager)
            .build()
        return Retrofit.Builder()
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(okClient)
            .baseUrl(BuildConfig.BASE_URL)
            .build().create(RestApi::class.java)

    }
}

class ResponseFunc<T> : Function<ResponseWrapper<T>, ObservableSource<T>> {
    override fun apply(t: ResponseWrapper<T>): ObservableSource<T> {
        return ObservableSource { it: Observer<in T> ->
            when {
                t.isOk() -> it.onNext(t.data)
                t.isAuthExpired() -> it.onError(ExpiredException(t.errMsg))
                else -> it.onError(Throwable(t.errMsg))
            }
        }
    }

}


//解析格式
class ResponseWrapper<T>(
    @SerializedName("status") var errCode: Int = -100,
    @SerializedName("msg") var errMsg: String,
    @SerializedName("data") var data: T
) {
    companion object {

        const val AUTH_EXPIRED_CODE = -99
    }

    fun isOk() = errCode == 0

    fun isAuthExpired() = errCode == AUTH_EXPIRED_CODE
}

//针对各种共性很高的 list 数据

class ListReponseWrapper<T>(
    var page: Int,
    var pages: Int,
    @SerializedName("list")
    var dataList: List<T>
) {
    val hasMore get() = page >= pages
}


abstract class ResponseBodyInterceptor : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val url = request.url().toString()
        val response = chain.proceed(request)
        response.body()?.let { responseBody ->
            val contentLength = responseBody.contentLength()
            val source = responseBody.source()
            source.request(Long.MAX_VALUE)
            var buffer = source.buffer()

            if ("gzip".equals(response.header("Content-Encoding"), ignoreCase = true)) {
                GzipSource(buffer.clone()).use { gzippedResponseBody ->
                    buffer = Buffer()
                    buffer.writeAll(gzippedResponseBody)
                }
            }

            val contentType = responseBody.contentType()
            val charset: Charset = contentType?.charset(StandardCharsets.UTF_8) ?: StandardCharsets.UTF_8
            if (contentLength != 0L) {
                return intercept(response, url, buffer.clone().readString(charset))
            }
        }
        return response
    }

    abstract fun intercept(response: Response, url: String, body: String): Response


}


object RestApiResponseInterceptor : ResponseBodyInterceptor() {


    //todo 模拟账户明细请求
    val accountListResponseData =
        "{\"status\":0,\"msg\":\"success\",\"data\":{\"total\":\"8\",\"list\":[{\"type\":\"8\",\"number\":\"-500000\",\"cost_text\":\"\\u7533\\u8bf7\\u63d0\\u73b050\\u5143, \\u624b\\u7eed\\u8d391\\u5143, \\u5b9e\\u9645\\u5230\\u8d2649\\u5143\",\"date\":\"2019-09-18 15:04:32\"},{\"type\":\"8\",\"number\":\"-500000\",\"cost_text\":\"\\u7533\\u8bf7\\u63d0\\u73b050\\u5143, \\u624b\\u7eed\\u8d391\\u5143, \\u5b9e\\u9645\\u5230\\u8d2649\\u5143\",\"date\":\"2019-09-18 15:04:32\"},{\"type\":\"8\",\"number\":\"-500000\",\"cost_text\":\"\\u7533\\u8bf7\\u63d0\\u73b050\\u5143, \\u624b\\u7eed\\u8d391\\u5143, \\u5b9e\\u9645\\u5230\\u8d2649\\u5143\",\"date\":\"2019-09-18 15:04:30\"},{\"type\":\"2\",\"number\":\"30000\",\"cost_text\":\"\\u9080\\u8bf7\\u5956\\u52b1(3\\u4eba)\",\"date\":\"2019-09-12 11:47:08\"},{\"type\":\"2\",\"number\":\"30000\",\"cost_text\":\"\\u9080\\u8bf7\\u5956\\u52b1(3\\u4eba)\",\"date\":\"2019-09-12 11:43:41\"},{\"type\":\"2\",\"number\":\"30000\",\"cost_text\":\"\\u9080\\u8bf7\\u5956\\u52b1(3\\u4eba)\",\"date\":\"2019-09-11 11:43:37\"},{\"type\":\"2\",\"number\":\"30000\",\"cost_text\":\"\\u9080\\u8bf7\\u5956\\u52b1(3\\u4eba)\",\"date\":\"2019-09-10 11:43:34\"},{\"type\":\"2003\",\"number\":\"10000\",\"cost_text\":\"\\u9080\\u8bf7\\u597d\\u53cb\",\"date\":\"2019-09-09 18:05:36\"}],\"page\":\"1\",\"hasmore\":0}}"

    val TAG = "ResponseInterceptor"
    override fun intercept(response: Response, url: String, body: String): Response {


//        if (url.contains("ucenter/goldz_list"))
//            return response.newBuilder()
//                .body(ResponseBody.create(response.body()?.contentType(), accountListResponseData)).build()

        //处理 ucenter/my_info 接口的错误

        Log.i(TAG, "intercept: $body")

        val errIndex = body.indexOf("{\"status\"")

        if (errIndex == 0) return response

        val responseString = body.substring(errIndex)

        Log.i(TAG, "intercept result: $responseString")

        return response.newBuilder().body(ResponseBody.create(response.body()?.contentType(), responseString)).build()
    }


}